USE business;
GO

-- jeli tabela istnieje w bazie danych ...
IF OBJECT_ID('dbo.Pracownicy_log_update') IS NOT NULL
	DROP TABLE dbo.Pracownicy_log_update;  -- ... to j usuwamy
GO

-- tworzymy now tabel zawierajc dwie kolumny
CREATE TABLE dbo.Pracownicy_log_update
(
	Data       DATETIME,
	instrukcja VARCHAR(300)
);


-- jeli istnieje wyzwalacz w bazie danych ...
IF OBJECT_ID('dbo.trg_log_update') IS NOT NULL
	DROP TRIGGER dbo.trg_log_update;  -- ... to go usuwamy
GO

-- tworzymy nowy wyzwalacz ...
CREATE TRIGGER dbo.trg_log_update
ON dbo.Pracownicy  -- ... na tabeli Pracownicy ...
FOR UPDATE         -- ... dla instrukcji UPDATE
AS
  -- dane z tabel inserted i deleted kopiowane s za pomoc szybkiej 
  -- nielogowanej instrukcji SELECT INTO do nowych tabel, na ktrych
  -- zakadany jest indeks w celu przyspieszenia dziaa w kursorze
	IF OBJECT_ID('dbo.___tmp_deleted') IS NOT NULL
		DROP TABLE dbo.___tmp_deleted;  -- jeli istnieje tabela, to jest usuwana
  -- skopiowanie tabeli deleted do nowej tabeli za pomoc nielogowanej (szybkiej!!!) 
  -- instrukcji SELECT INTO
	SELECT * INTO dbo.___tmp_deleted FROM Deleted;
  -- zaoenie indeksu na tabeli 
	CREATE UNIQUE CLUSTERED INDEX idx_del 
	ON ___tmp_deleted(Id);

	IF OBJECT_ID('dbo.___tmp_inserted') IS NOT NULL
		DROP TABLE dbo.___tmp_inserted;
	SELECT * INTO dbo.___tmp_inserted FROM Inserted;

	CREATE UNIQUE CLUSTERED INDEX idx_ins 
	ON ___tmp_inserted(Id);

  -- deklaracja zmiennych do kursora
	DECLARE
		@ins_Id        INT,
		@ins_Imie      VARCHAR(20),
		@ins_Nazwisko  VARCHAR(30),
		@ins_Pensja    MONEY,
		@ins_Id_dzialu INT,
		@del_Id        INT,
		@del_Imie      VARCHAR(20),
		@del_Nazwisko  VARCHAR(30),
		@del_Pensja    MONEY,
		@del_Id_dzialu INT,
		@sql           VARCHAR(300); -- ... i zmiennej przechowujcej kod zapytania

  -- deklaracja kursora, pobierajcego wszystkie dane z tabel
	DECLARE cur_del CURSOR FAST_FORWARD FOR
	SELECT 
		ins.Id,
		ins.Imie,
		ins.Nazwisko,
		ins.Pensja,
		ins.Id_dzialu,
		del.Id,
		del.Imie,
		del.Nazwisko,
		del.Pensja,
		del.Id_dzialu
	FROM dbo.___tmp_inserted ins, dbo.___tmp_deleted del
	WHERE ins.Id = del.Id;

  -- otwieranie kursora
	OPEN cur_del;
  -- pobranie danych z kursora do zmiennych 
	FETCH NEXT FROM cur_del INTO
	@ins_Id, @ins_Imie, @ins_Nazwisko, @ins_Pensja, @ins_Id_dzialu,
	@del_Id, @del_Imie, @del_Nazwisko, @del_Pensja, @del_Id_dzialu;
	-- dopki s dane w kursorze
	WHILE @@FETCH_STATUS = 0
	BEGIN 
         -- tworzona jest instrukcja UPDATE aktualizujca wartoci poszczeglnych 
		-- kolumn w tabeli Pracownicy  dziki tej instrukcji bdzie mona przywrci 
-- starsze wartoci poszczeglnych pl
		SET @sql = 'UPDATE dbo.Pracownicy SET '
		+ 'Imie = ' + QUOTENAME(@ins_Imie, '''') + ', '
		+ 'Nazwisko = ' + QUOTENAME(@ins_Nazwisko ,'''') + ', '
		+ 'Pensja = ' + CAST(@ins_Pensja AS VARCHAR) + ', '
		+ 'Id_dzialu = ' + cAST(@ins_Id_dzialu AS VARCHAR) + ' '
		+ 'WHERE '
		+ 'Id = ' + CAST(@ins_Id AS VARCHAR) + ' AND '
		+ 'Imie = ' + QUOTENAME(@ins_Imie, '''') + ' AND '
		+ 'Nazwisko = ' + QUOTENAME(@ins_Nazwisko, '''') + ' AND '
		+ 'Pensja = ' + CAST(@ins_Pensja AS VARCHAR) + ' AND '
		+ 'Id_dzialu = ' + CAST(@ins_Id_dzialu AS VARCHAR);

		-- wstawienie daty i kodu instrukcji do tabeli logw
		INSERT INTO dbo.Pracownicy_log_update (Data, instrukcja) 
VALUES(getdate(), @sql);
		
 		-- pobranie kolejnego wiersza z kursora
		FETCH NEXT FROM cur_del INTO
		@ins_Id, @ins_Imie, @ins_Nazwisko, @ins_Pensja, @ins_Id_dzialu,
		@del_Id, @del_Imie, @del_Nazwisko, @del_Pensja, @del_Id_dzialu;
	END; -- koniec ptli

	CLOSE cur_del;        -- zamknicie kursora
	DEALLOCATE cur_del;   -- zwolnienie zasobw zwizanych z kursorem
  -- usunicie tabel tymczasowych
	IF OBJECT_ID('dbo.___tmp_deleted') IS NOT NULL
		DROP TABLE dbo.___tmp_deleted;  
	IF OBJECT_ID('dbo.___tmp_inserted') IS NOT NULL
		DROP TABLE dbo.___tmp_inserted;  
